﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HopfieldNetwork.Core
{
    /// <summary>
    /// Representa una Neurona Artificial de Hopfield
    /// </summary>
    public class Neuron
    {
        /// <summary>
        /// Estado actual de la memoria
        /// </summary>
        /// <seealso cref="HopfieldNetwork.Core.NeuronState"/>
        private int state;


        /// <summary>
        /// Umbral de Activacion
        /// 
        /// por lo regular, el umbral de activacion para
        /// las redes neuronales de hopfield son 0
        /// </summary>
        private int umbral = 0;

        /// <summary>
        /// Crea una nueva neurona
        /// </summary>
        public Neuron()
        {
            int r = new Random().Next(2);
            switch (r)
            {
                case 0: state = NeuronState.InActive; break;
                case 1: state = NeuronState.Active; break;
            } 
        }


        /// <summary>
        /// Acceso al Estado Actual de la Neurona
        /// </summary>
        public int State
        {
            get { return state; }
            internal set { state = value; }
        }

        /// <summary>
        /// Acceso al Umbral de la Neurona
        /// </summary>
        public int Umbral
        {
            get { return umbral; }
            set { umbral = value; }
        }

        /// <summary>
        /// Evaluacion de Cambio de Estado
        /// 
        /// Esta evaluacion se realiza para calcular el nuevo
        /// estado de la neurnona:
        ///     x(t+1)=|Activa, si neti(t) > Umbral 
        ///            |Sin Cambio, su neti(t) = Umbral 
        ///            |Inactiva, si neti(t) < Umbral
        /// 
        /// Se necesita saber si la neurona cambia de estado
        /// para recalcular la funcion de energia
        /// Ademas para ir observando cuando la red
        /// esta convergiendo
        /// </summary>
        /// <param name="net">Funcion net evaluada para la neurona</param>
        /// <returns>Retorna si la Neurona ha sido modificada o no</returns>
        internal bool ChageState(int net)
        {
            bool isChState = false;
            if (net < umbral && this.State==NeuronState.Active)
            {
                this.State = NeuronState.InActive;
                isChState = true;
            }
            else if (net > umbral && this.State==NeuronState.InActive)
            {
                this.State = NeuronState.Active;
                isChState = true;
            }
            return isChState;
        }
    }
}
